import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
import { CreateWebsiteRequest, UpdateWebsiteRequest } from '../types/group';
import { Group } from './Group';
import { AppDataSource } from '../config/database';

@Entity('websites')
export class Website {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column({ type: 'varchar', length: 200 })
  name!: string;

  @Column({ type: 'text', nullable: true })
  description?: string;

  @Column({ type: 'varchar', length: 500 })
  url!: string;

  @Column({ type: 'varchar', length: 500, nullable: true })
  logo?: string;

  @Column({ type: 'uuid' })
  groupId!: string;

  @Column({ type: 'int', default: 0 })
  order!: number;

  @Column({ type: 'boolean', default: true })
  isActive!: boolean;

  @CreateDateColumn()
  createdAt!: Date;

  @UpdateDateColumn()
  updatedAt!: Date;

  @ManyToOne(() => Group, group => group.websites, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'groupId' })
  group!: Group;
}

export class WebsiteModel {
  private static getRepository() {
    return AppDataSource.getRepository(Website);
  }

  // 获取所有网站
  static async findAll(): Promise<Website[]> {
    const repository = this.getRepository();
    return await repository.find({
      order: { order: 'ASC' },
      relations: ['group']
    });
  }

  // 根据分组ID获取网站
  static async findByGroupId(groupId: string): Promise<Website[]> {
    const repository = this.getRepository();
    return await repository.find({
      where: { groupId },
      order: { order: 'ASC' },
      relations: ['group']
    });
  }

  // 根据ID获取网站
  static async findById(id: string): Promise<Website | null> {
    const repository = this.getRepository();
    return await repository.findOne({
      where: { id },
      relations: ['group']
    });
  }

  // 创建网站
  static async create(data: CreateWebsiteRequest): Promise<Website> {
    const repository = this.getRepository();
    
    // 如果没有指定order，设置为该分组下最大order + 1
    if (!data.order) {
      const maxOrder = await repository.maximum('order', { groupId: data.groupId }) || 0;
      data.order = maxOrder + 1;
    }
    
    const website = repository.create(data);
    return await repository.save(website);
  }

  // 更新网站
  static async update(id: string, data: UpdateWebsiteRequest): Promise<Website | null> {
    const repository = this.getRepository();
    
    await repository.update(id, data);
    return await this.findById(id);
  }

  // 删除网站
  static async delete(id: string): Promise<boolean> {
    const repository = this.getRepository();
    
    const result = await repository.delete(id);
    return (result.affected || 0) > 0;
  }

  // 根据分组ID删除所有网站
  static async deleteByGroupId(groupId: string): Promise<number> {
    const repository = this.getRepository();
    
    const result = await repository.delete({ groupId });
    return result.affected || 0;
  }

  // 检查URL是否已存在
  static async existsByUrl(url: string, excludeId?: string): Promise<boolean> {
    const repository = this.getRepository();
    
    const query = repository.createQueryBuilder('website')
      .where('website.url = :url', { url });
    
    if (excludeId) {
      query.andWhere('website.id != :excludeId', { excludeId });
    }
    
    const count = await query.getCount();
    return count > 0;
  }

  // 搜索网站
  static async search(query: string): Promise<Website[]> {
    const repository = this.getRepository();
    
    return await repository.createQueryBuilder('website')
      .leftJoinAndSelect('website.group', 'group')
      .where('LOWER(website.name) LIKE LOWER(:query)', { query: `%${query}%` })
      .orWhere('LOWER(website.description) LIKE LOWER(:query)', { query: `%${query}%` })
      .orWhere('LOWER(website.url) LIKE LOWER(:query)', { query: `%${query}%` })
      .orderBy('website.order', 'ASC')
      .getMany();
  }

  // 获取网站数量
  static async count(): Promise<number> {
    const repository = this.getRepository();
    return await repository.count();
  }

  // 获取分组下的网站数量
  static async countByGroupId(groupId: string): Promise<number> {
    const repository = this.getRepository();
    return await repository.count({ where: { groupId } });
  }

  // 重新排序网站
  static async reorder(websiteOrders: { id: string; order: number }[]): Promise<void> {
    const repository = this.getRepository();
    
    for (const { id, order } of websiteOrders) {
      await repository.update(id, { order });
    }
  }

  // 切换网站状态
  static async toggleActive(id: string): Promise<Website | null> {
    const repository = this.getRepository();
    
    const website = await this.findById(id);
    if (website) {
      await repository.update(id, { isActive: !website.isActive });
      return await this.findById(id);
    }
    return null;
  }
}